package com.xh.generate.core;

import com.xh.generate.bean.CodeFilePath;
import com.xh.generate.bean.Configuration;
import com.xh.generate.bean.PackagePath;
import com.xh.generate.bean.TableInfo;
import com.xh.generate.utils.DataMapUtil;
import com.xh.generate.utils.FileUtil;
import com.xh.generate.utils.GenerateUtil;
import com.xh.generate.utils.StringUtil;

import java.io.File;
import java.io.IOException;
import java.util.Map;

/**
 * @Name GenerateService
 * @Description 代码生成service
 * @Author wen
 * @Date 2020-03-29
 */
public class CoreGenerater {

    private final static Configuration CONFIGURATION = DBManager.getConf();

    private final static CodeFilePath CONF_CODE_FILE_PATH = CONFIGURATION.getCodeFilePath();

    private final static PackagePath CONF_PACKAGE_PATH = CONFIGURATION.getPackagePath();

    private static final Map<String, Object> data = DataMapUtil.DATA;

    public static void generate(TableInfo tableInfo) throws IOException {
        String tname = tableInfo.getTname();
        //如果数据库表名有前缀，就去掉前缀
        if (StringUtil.isNotEmpty(CONFIGURATION.getTableNamePrefix())) {
            tname = tname.replace(CONFIGURATION.getTableNamePrefix(), "");
        }
        //po类名称，如 User
        String poClassName = StringUtil.firstAndToCamel(tname);
        //设置公共属性值, po类名称，如 User
        data.put("poClassName", poClassName);
        //po实例名称，如 user
        data.put("poInstance", StringUtil.firstChar2LowerCase(poClassName));
        //vo类名称，如 UserVo
        data.put("voClassName", poClassName + "Vo");
        //vo实例名称，如 userVo
        data.put("voInstance", StringUtil.firstChar2LowerCase(poClassName + "Vo"));
        //po包路径
        data.put("poPackage", CONF_PACKAGE_PATH.getPoPackage());
        //vo包路径
        data.put("voPackage", CONF_PACKAGE_PATH.getVoPackage());
        //mapper包路径
        data.put("mapperPackage", CONF_PACKAGE_PATH.getMapperPackage() + ".mapper");
        //baseMapper包路径
        data.put("baseMapperPackage", CONF_PACKAGE_PATH.getMapperPackage() + ".base");
        //Service包路径
        data.put("servicePackage", CONF_PACKAGE_PATH.getServicePackage());
        //主键java类型
        data.put("priKeyJavaType", tableInfo.getPriKeyFieldType());
        //1.生成po层java代码
        generatePo(poClassName, tableInfo);
        //2.生成mapper层java代码
        generateMapper(poClassName);
        //3.生成service层java代码
        generateServiceImpl(poClassName);
        //4.生成service层java代码
        generateController(poClassName);
    }

    /**
     * 生成项目配置文件
     */
    public static void generateConfig() throws IOException {
        String configPath = CONF_CODE_FILE_PATH.getConfigPath();
        String mapperPathFile = configPath + "MybatisConfig.java";
        if (!new File(mapperPathFile).exists()) {
            data.put("configPackage", CONF_PACKAGE_PATH.getConfigPackage());
            FileUtil.createDirectory(configPath);
            //MybatisConfig文件
            GenerateUtil.export(mapperPathFile, "MybatisConfig", data);
        }
    }

    /**
     * @param poClassName
     * @param tableInfo
     * @return void
     * @Name generatePo和Vo对象
     * @Description 生成po层java代码
     * @Author wen
     * @Date 2020/3/29
     */
    public static void generatePo(String poClassName, TableInfo tableInfo) throws IOException {
        //设置数据库表名称
        data.put("tableName", tableInfo.getTname());
        //设置字段
        data.put("columns", tableInfo.getColumns().values());
        String poPath = CONF_CODE_FILE_PATH.getPoPath();
        FileUtil.createDirectory(poPath);
        //生成文件全路径
        String poPathFile = poPath + poClassName + ".java";
        //生成mapper.xml文件
        generateMapperXml(poClassName);
        //生成po.java文件
        GenerateUtil.export(poPathFile, "Po", data);
    }

    public static void generateMapperXml(String poClassName) throws IOException {
        FileUtil.createDirectory(CONF_CODE_FILE_PATH.getMapperXmlPath());
        //生成文件全路径
        String poPathFile = CONF_CODE_FILE_PATH.getMapperXmlPath() + poClassName + "Mapper.xml";
        //生成po.java文件
        GenerateUtil.export(poPathFile, "MapperXml", data);
    }

    /**
     * @param poClassName
     * @return void
     * @Name generateMapper
     * @Description 生成mapper层java代码
     * @Author wen
     * @Date 2020/3/29
     */
    public static void generateMapper(String poClassName) throws IOException {
        String mapperPath = CONF_CODE_FILE_PATH.getMapperPath();
        //先生成IBaseMapper文件
        generateBaseMapper(mapperPath);
        mapperPath = mapperPath + "mapper/";
        FileUtil.createDirectory(mapperPath);
        //生成Mapper.java文件
        String mapperPathFile = mapperPath + poClassName + "Mapper.java";
        GenerateUtil.export(mapperPathFile, "Mapper", data);
    }

    public static void generateServiceImpl(String poClassName) throws IOException {
        data.put("enumsPackage", CONF_PACKAGE_PATH.getCommonsPackage() + ".enums");
        data.put("exceptionPackage", CONF_PACKAGE_PATH.getCommonsPackage() + ".exception");
        String servicePath = CONF_CODE_FILE_PATH.getServicePath();
        //先生成Service文件
        generateService(poClassName, servicePath);
        //生成文件全路径
        String servicePathFile = servicePath + "impl/" + poClassName + "ServiceImpl.java";
        //生成ServiceImpl.java文件
        GenerateUtil.export(servicePathFile, "ServiceImpl", data);
    }

    public static void generateController(String poClassName) throws IOException {
        //设置Controller包路径
        data.put("controllerPackage", CONF_PACKAGE_PATH.getControllerPackage());
        String controllerPath = CONF_CODE_FILE_PATH.getControllerPath();
        FileUtil.createDirectory(controllerPath);
        //生成文件全路径
        String controllerPathFile = controllerPath + poClassName + "Controller.java";
        //生成Controller.java文件
        GenerateUtil.export(controllerPathFile, "Controller", data);
    }


    private static void generateService(String poClassName, String servicePath) throws IOException {
        FileUtil.createDirectory(servicePath + "impl/");
        //生成文件全路径
        String servicePathFile = servicePath + poClassName + "Service.java";
        //生成Service.java文件
        GenerateUtil.export(servicePathFile, "Service", data);
    }

    /**
     * @param mapperPath
     * @return void
     * @Name generateBaseMapper
     * @Description 生成IBaseMapper代码
     * @Author wen
     * @Date 2020/3/29
     */
    private static void generateBaseMapper(String mapperPath) throws IOException {
        String baseMapperPath = mapperPath + "/base/";
        FileUtil.createDirectory(baseMapperPath);
        //生成文件全路径
        String baseMapperPathFile = baseMapperPath + "IBaseMapper.java";
        //生成IbaseMapper.java文件
        GenerateUtil.export(baseMapperPathFile, "BaseMapper", data);
    }

    /**
    * @Name generateCore
    * @Description 生成核心代码
    * @Author wen
    * @Date 2020/3/29
    * @param
    * @return void
    */
    public static void generateCore() throws IOException {
        String diskUrl = CONFIGURATION.getDiskUrl();
        if (StringUtil.isNotEmpty(diskUrl) && !new File(diskUrl).exists()) {
            FileUtil.createDirectory(diskUrl);
        }
        Map<String, TableInfo> tables = TableContext.getTables();
        String generateTables = CONFIGURATION.getGenerateTables();
        if (StringUtil.isEmpty(generateTables)) {
            //生成所有表代码
            for (String key : tables.keySet()) {
                CoreGenerater.generate(tables.get(key));
            }
        } else {
            //根据配置生成代码
            String[] tableNames = generateTables.split(",");
            for (String tableName : tableNames) {
                TableInfo tableInfo = tables.get(tableName);
                if (null != tableInfo) {
                    CoreGenerater.generate(tableInfo);
                }
            }
        }
        System.out.println(" Core CODE BUILD SUCCESS!!! ");
    }


}
